package org.zwy.gradetrack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zwy.gradetrack.entity.Indicator;
import org.zwy.gradetrack.entity.TeacherEvaluation;
import org.zwy.gradetrack.mapper.TeacherEvaluationMapper;
import org.zwy.gradetrack.service.IndicatorService;
import org.zwy.gradetrack.service.TeacherEvaluationService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.math.BigDecimal;

/**
 * 教师评价Service实现类
 */
@Service
public class TeacherEvaluationServiceImpl extends ServiceImpl<TeacherEvaluationMapper, TeacherEvaluation> implements TeacherEvaluationService {

    @Autowired
    private IndicatorService indicatorService;

    @Override
    public Page<TeacherEvaluation> pageEvaluations(Integer current, Integer size, Long teacherId, Long studentId, Long indicatorId) {
        Page<TeacherEvaluation> page = new Page<>(current, size);
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        
        if (teacherId != null) {
            wrapper.eq(TeacherEvaluation::getTeacherId, teacherId);
        }
        if (studentId != null) {
            wrapper.eq(TeacherEvaluation::getStudentId, studentId);
        }
        if (indicatorId != null) {
            wrapper.eq(TeacherEvaluation::getIndicatorId, indicatorId);
        }
        
        wrapper.orderByDesc(TeacherEvaluation::getCreateTime);
        
        return page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TeacherEvaluation createEvaluation(TeacherEvaluation evaluation) {
        // 检查指标点是否存在
        Indicator indicator = indicatorService.getById(evaluation.getIndicatorId());
        if (indicator == null) {
            throw new RuntimeException("指标点不存在");
        }
        
        // 检查是否已存在评价
        if (existsEvaluation(evaluation.getTeacherId(), evaluation.getStudentId(), evaluation.getIndicatorId())) {
            throw new RuntimeException("该指标点已有评价数据");
        }
        
        // 设置创建和更新时间
        LocalDateTime now = LocalDateTime.now();
        evaluation.setCreateTime(now);
        evaluation.setUpdateTime(now);
        
        save(evaluation);
        return evaluation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TeacherEvaluation updateEvaluation(Long id, TeacherEvaluation evaluation) {
        // 检查评价是否存在
        TeacherEvaluation existingEvaluation = getById(id);
        if (existingEvaluation == null) {
            throw new RuntimeException("评价数据不存在");
        }
        
        // 检查指标点是否存在
        Indicator indicator = indicatorService.getById(evaluation.getIndicatorId());
        if (indicator == null) {
            throw new RuntimeException("指标点不存在");
        }
        
        // 检查是否已存在其他评价
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeacherEvaluation::getTeacherId, evaluation.getTeacherId())
               .eq(TeacherEvaluation::getStudentId, evaluation.getStudentId())
               .eq(TeacherEvaluation::getIndicatorId, evaluation.getIndicatorId())
               .ne(TeacherEvaluation::getId, id);
        
        if (count(wrapper) > 0) {
            throw new RuntimeException("该指标点已有其他评价数据");
        }
        
        // 设置更新时间
        evaluation.setUpdateTime(LocalDateTime.now());
        evaluation.setId(id);
        
        updateById(evaluation);
        return evaluation;
    }

    @Override
    public Map<String, Object> getStatistics(Long teacherId, Long studentId, Long indicatorId) {
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        if (teacherId != null) {
            wrapper.eq(TeacherEvaluation::getTeacherId, teacherId);
        }
        if (studentId != null) {
            wrapper.eq(TeacherEvaluation::getStudentId, studentId);
        }
        if (indicatorId != null) {
            wrapper.eq(TeacherEvaluation::getIndicatorId, indicatorId);
        }
        
        List<TeacherEvaluation> evaluations = list(wrapper);
        
        // 计算统计数据
        return evaluations.stream()
            .collect(Collectors.groupingBy(
                evaluation -> evaluation.getIndicatorId().toString(),
                Collectors.collectingAndThen(
                    Collectors.toList(),
                    list -> {
                        double avgScore = list.stream()
                            .mapToDouble(e -> e.getScore().doubleValue())
                            .average()
                            .orElse(0.0);
                        
                        double maxScore = list.stream()
                            .mapToDouble(e -> e.getScore().doubleValue())
                            .max()
                            .orElse(0.0);
                        
                        double minScore = list.stream()
                            .mapToDouble(e -> e.getScore().doubleValue())
                            .min()
                            .orElse(0.0);
                        
                        // 计算评价分布
                        Map<Double, Long> scoreDistribution = list.stream()
                            .collect(Collectors.groupingBy(
                                e -> Math.floor(e.getScore().doubleValue()),
                                Collectors.counting()
                            ));
                        
                        return Map.of(
                            "averageScore", avgScore,
                            "maxScore", maxScore,
                            "minScore", minScore,
                            "count", list.size(),
                            "scoreDistribution", scoreDistribution
                        );
                    }
                )
            ));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchImport(List<TeacherEvaluation> evaluations) {
        // 验证数据
        for (TeacherEvaluation evaluation : evaluations) {
            // 检查指标点是否存在
            Indicator indicator = indicatorService.getById(evaluation.getIndicatorId());
            if (indicator == null) {
                throw new RuntimeException("指标点ID " + evaluation.getIndicatorId() + " 不存在");
            }
            
            // 检查是否已存在评价
            if (existsEvaluation(evaluation.getTeacherId(), evaluation.getStudentId(), evaluation.getIndicatorId())) {
                throw new RuntimeException("教师ID " + evaluation.getTeacherId() + 
                    " 对学生ID " + evaluation.getStudentId() + 
                    " 的指标点 " + evaluation.getIndicatorId() + " 已有评价数据");
            }
            
            // 设置创建和更新时间
            LocalDateTime now = LocalDateTime.now();
            evaluation.setCreateTime(now);
            evaluation.setUpdateTime(now);
        }
        
        // 批量保存
        saveBatch(evaluations);
    }

    @Override
    public boolean existsEvaluation(Long teacherId, Long studentId, Long indicatorId) {
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeacherEvaluation::getTeacherId, teacherId)
               .eq(TeacherEvaluation::getStudentId, studentId)
               .eq(TeacherEvaluation::getIndicatorId, indicatorId);
        
        return count(wrapper) > 0;
    }

    @Override
    public List<TeacherEvaluation> getTeacherStudentEvaluations(Long teacherId, Long studentId) {
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeacherEvaluation::getTeacherId, teacherId)
               .eq(TeacherEvaluation::getStudentId, studentId)
               .orderByDesc(TeacherEvaluation::getCreateTime);
        
        return list(wrapper);
    }

    @Override
    public List<TeacherEvaluation> getStudentIndicatorEvaluations(Long studentId, Long indicatorId) {
        LambdaQueryWrapper<TeacherEvaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeacherEvaluation::getStudentId, studentId)
               .eq(TeacherEvaluation::getIndicatorId, indicatorId)
               .orderByDesc(TeacherEvaluation::getCreateTime);
        
        return list(wrapper);
    }

    @Override
    public BigDecimal getLatestEvaluationScore(Long indicatorId, Integer evaluationYear) {
        return baseMapper.selectLatestEvaluationScore(indicatorId, evaluationYear);
    }
}